from django.shortcuts import render
from django.views import View
import json
from django.http import JsonResponse
from rest_framework import generics
from rest_framework import mixins
from rest_framework import serializers
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import CreateModelMixin
from rest_framework.response import Response
from rest_framework.views import APIView
from apps.books.models import BookInfo, HeroInfo
from .serializers import BookSerializer, BookModelSerializer, HeroModelSerializer

'''APIView类的后端实现'''
# class BooksAPIView(APIView):
#     def get(self,requset):
#         # queryset = BookInfo.objects.filter(pk__lt=4).order_by("-id")
#         # 图书
#         # queryset = BookInfo.objects.all()
#         # serializer = BookModelSerializer(queryset, many=True)
#         # 英雄
#         queryset = HeroInfo.objects.all()
#         serializer = HeroModelSerializer(queryset, many=True)
#         blist = serializer.data
#         return Response(blist)
#     def post(self,request):
#        dict = request.data
#        # # 图书
#        # serializer = BookSerializer(data=dict)
#        # 英雄
#        serializer = HeroModelSerializer(data=dict)
#        serializer.is_valid(raise_exception=True)
#        instance=serializer.save()
#        # 响应
#        return Response(serializer.data,status=201)
# class BookAPIView(APIView):
#     def get(self,request,pk):
#         try:#图书
#             # instance=BookInfo.objects.get(pk=pk)
#             instance=HeroInfo.objects.get(pk=pk)   #英雄
#         except:
#             return Response(status=404)
#         # serializer = BookModelSerializer(instance)
#         serializer = HeroModelSerializer(instance)
#         blist = serializer.data
#         return Response(blist)
#     def put(self,request,pk):
#         try:
#             # instance=BookInfo.objects.get(pk=pk)
#             instance=HeroInfo.objects.get(pk=pk)  #英雄
#         except:
#             return Response(status=404)
#         dict=request.data
#         print(dict)
#         # serializer = BookModelSerializer(instance,data=dict)
#         serializer = HeroModelSerializer(instance,data=dict)  #英雄
#         serializer.is_valid(raise_exception=True)
#         serializer.save()
#         return Response(serializer.data,status=201)
#
#     def delete(self, request, pk):
#         try:
#             # instance=BookInfo.objects.get(pk=pk)
#             instance=HeroInfo.objects.get(pk=pk)  #英雄
#         except:
#             return Response(status=404)
#         instance.delete()
#         return Response(status=204)

'''继承ModelMixin的五个类的后端实现'''
# class BooksGenericAPIView(mixins.ListModelMixin,GenericAPIView,CreateModelMixin):
#     # 指定查询集
#     queryset = BookInfo.objects.all()
#     # 指定序列化器
#     serializer_class = BookModelSerializer
#     def get(self,request):
#         return self.list(request)
#     def post(self,request):
#         return self.create(request)
# class BookGenericAPIView(mixins.RetrieveModelMixin,GenericAPIView):
#     queryset = BookInfo.objects.all()
#     serializer_class = BookModelSerializer
#     def get(self,request,pk):
#         return self.retrieve(request,pk)
'''继承generics.genericsAPIView的五个类的后端实现'''
class BooksGenericAPIView(generics.ListCreateAPIView):
    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器
    serializer_class = BookModelSerializer
class BookssGenericAPIView(generics.RetrieveUpdateDestroyAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookModelSerializer
'''继承generics.genericsAPIView的最终版本'''
# class BooksSet(mixins.UpdateModelMixin,mixins.ListModelMixin,mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.CreateModelMixin,viewsets.ViewSet):
#     queryset = BookInfo.objects.all()
#     serializer_class = BookModelSerializer

# viewsets.ModelViewSet类中有所有的曾删改查
class BooksViewSet(viewsets.ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookModelSerializer
    # 过滤条件  条件以查询参数条件出现在url中
    filter_fields = ('btitle', 'bread')
    # 排序   条件以查询参数条件出现在url中
    filter_backends = [OrderingFilter]
    ordering_fields = ('id', 'bread', 'bpub_date')

    # 自动为视图集中的自定义方法生成路由 /books/say/
    @action(methods=["GET"],detail=False)
    def say(self,request):
        return Response({"msg":"say"})
    # 接收主键操作某一个商品
    # 自动为视图集中的自定义方法生成路由 /books/pk/say/
    @action(methods=["GET"],detail=True)
    def say(self,request):
        return Response({"msg":"say"})

# class BooksView(View):
#     def get(self,request):
#         queryset = BookInfo.objects.all()
#         # 模型类转字典进行封装  查询时用  将实例化对象转成字典后反给前端
#         # 取多个  queryset模型类的查询集
#         serializer = BookModelSerializer(queryset,many=True)
#         blist = serializer.data
#         return JsonResponse(blist,safe=False)
#     def post(self,request):
#         # 接受
#         dict = json.loads(request.body.decode())
#         # 验证
#         serializer = BookSerializer(data=dict)
#         if not serializer.is_valid():
#             # 400为客户端发给服务器的数据有误
#             return JsonResponse(serializer.errors,status=400)
#         # 处理  创建  instance为对象
#         instance=serializer.save()
#         # 响应
#         return JsonResponse(serializer.data,status=201)
# class BookView(View):
#     def put(self,request,pk):
#         try:
#             instance = BookInfo.objects.get(pk=pk)
#         except:
#             return JsonResponse(status=500)
#         dict = json.loads(request.body.decode())
#         # 验证
#         # data  不一定合法  如果不合法serializer.validated_data为空字典
#         # 合法时serializer.validated_data是格式化后的数据  data为原始数据  类型为字符串
#         serializer = BookSerializer(instance,data=dict)
#         if not serializer.is_valid():
#             # 400为客户端发给服务器的数据有误
#             return JsonResponse(serializer.errors, status=400)
#         # 处理  修改  instance为对象
#         instance = serializer.save()
#         # 响应
#         return JsonResponse(serializer.data, status=201)
#     # 序列化
#     # # 模型类转字典进行封装  查询时用  将实例化对象转成字典后反给前端
#     # # 取多个  queryset模型类的查询集
#     # serializer = BookSerializer(queryset,many=True)
#     # blist = serializer.data
#     # # 取一个  book为模型类的一个对象
#     # serializer = BookSerializer(book)
#     # blist = serializer.data



#
























# # 反序列化
# serializer = BookSerializer(data=json_dict)
# # 成功则返回数据
# if serializer.is_valid():
#     return JsonResponse(serializer.validated_data)
# # 失败返回数据给后台
# else:
#     serializer.errors
#     return JsonResponse(serializer.errors)


'''继承View的后端实现'''
# from apps.books.serializers import HeroSerializer
#
# class HerosView(View):
#     def get(self,request):
#         heros = HeroInfo.objects.all()
#         serializers = HeroSerializer(heros,many=True)
#         return JsonResponse(serializers.data,safe=False)
#     def post(self,requset):
#         # 接受参数
#         dict = json.loads(requset.body.decode())
#         # 检验参数
#         serializer = HeroSerializer(data=dict)
#         if serializer.is_valid(): # False
#             return JsonResponse(serializer.validated_data)
#         else:
#             return JsonResponse(serializer.errors)
#         # 传参时拆包的使用
#         # wasd(1,2,3)===>a=[1,2,3]===>wasd(*a)
#         # wasd(a=1,b=2,c=3)===>d=[a:1,b:2,c:3]===>wasd(**d)
#         # 将字典转换成a=1,b=2的格式  能且仅能在传参时使用
#         # HeroInfo.objects.create(**serializer.validated_data)
#         # hero = HeroInfo.objects.create(
#         #     hname = dict['hname'],
#         #     hcomment = dict['hcomment'],
#         #     hbook_id = dict['hbook_id']
#         # )
#         # return JsonResponse(
#         #     {"id":hero.id,"hname":hero.hname},status=201
#         # )
# class HeroView(View):
#     def get(self,requset,pk):
#         hero = HeroInfo.objects.get(pk=pk)
#         serializers = HeroSerializer(hero)
#         return JsonResponse(serializers.data)
#     def put(self,requset,pk):
#         dict = json.loads(requset.body.decode())
#         hero = HeroInfo.objects.get(pk=pk)
#         # hero.hname=dict['hname']
#         hero.hcomment=dict['hcomment']
#         hero.hbook_id=dict['hbook_id']
#         hero.save()
#         return JsonResponse(
#             {"id": hero.id, "hname": hero.hname}, status=201
#         )
#     def delete(self,requset,pk):
#         hero = HeroInfo.objects.get(pk=pk)
#         hero.delete()
#         return JsonResponse({}, status=204)